package org.jeecg.modules.simulator.model.line.station.station;

import lombok.Setter;

import org.jeecg.modules.simulator.jsonot.NumPeopEnStationApiInfo;
import org.jeecg.modules.simulator.jsonot.ODProbabilityApiInfo;
import org.jeecg.modules.simulator.model.line.Line;
import org.jeecg.modules.simulator.rooter.LineRooter;

import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * @program: simulator-b20240918
 * @description:
 * @author: renzhg
 * @create: 2024-10-24 10:44
 **/


public class HistoryOdParamService {
    private static final Logger logger = LoggerFactory.getLogger(HistoryOdParamService.class);

    @Setter
    Map<String, LineRooter> lineRooterMap = new HashMap<>();
    //按线路分的station
    @Setter
    Map<String, List<Station>> linesStationMap = new HashMap<>();

    @Setter
    Map<String, Line> lineMap = new HashMap<>();

    //配置历史数据所需要的数据
    /**
     * @description:
     * 1、设定站点业务参数：1、进站里面人数的OD概率 2、每秒进站人数
     * 2、 od数据处理--按要求的线路ID过滤线路信息
     *
     * @author:  renzhg
     * @date:  2024/11/15 17:06
     **/
    public void  assignInitHistoryParam(Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap,
                                       Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap) {


        //初始化进站数据数据
        //设定站点业务参数：1、进站里面人数的OD概率 2、每秒进站人数
        initHisInputsParam(numPeopEnStationApiInfoMap);
        //od数据处理--按要求的线路ID过滤线路信息
        filterPersonOdRatio(odProbabilityApiInfoMap);
        //历史OD数据匹配
//        filterPersonOdRatio(odProbabilityApiInfoMap);
        OdParamOperate(odProbabilityApiInfoMap);
        logger.debug("assignInitHistoryParam");
    }

//    private void filterNumPeopEnStationApiInfo(Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap) {
//        numPeopEnStationApiInfoMap.forEach((k, v) -> {
//            List<String> idlist = linesStationMap.get(k).stream()
//                    .map(Station::getId) // 提取每个 Station 的 name
//                    .collect(Collectors.toList());// 收
//            Map<String, NumPeopEnStationApiInfo> numPeopEnStationApiInfoMap2 = new HashMap<>();
//            v.forEach((k1, v1) -> {
//                if (idlist.contains(k1)) {
//                    numPeopEnStationApiInfoMap2.put(k1, v1);
//                }
//            });
//            v.clear();
//            v.putAll(numPeopEnStationApiInfoMap2);
//        });
//
//    }


    //od数据处理--按要求的线路ID过滤线路信息
    /**
     * @description: od数据处理--按要求的线路ID过滤线路信息
     *
     * @author:  renzhg
     * @date:  2024/11/15 17:14
     **/
    public void filterPersonOdRatio(Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap) {
        Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap2 = new HashMap<>();
        //过滤OD概率
        odProbabilityApiInfoMap.forEach((k, v) -> {
            //根据OD的站点id，提取前两位，判断是否是参与计算的线路
            if (containsPrefixInList(k, lineMap.keySet())) {
                odProbabilityApiInfoMap2.put(k, v);
            }
        });
        removeEntriesNotInMap1(odProbabilityApiInfoMap2, odProbabilityApiInfoMap);
    }

    public boolean containsPrefixInList(String input, Set<String> stringList) {
        // 分割输入字符串
        String[] parts = input.split("_");
        // 获取前两位
        String firstPart = parts[0].substring(0, 2); // "04"
        String secondPart = parts[1].substring(0, 2); // "03"
        // 检查前两位是否在列表中
        return stringList.contains(firstPart) && stringList.contains(secondPart);
    }

    public void removeEntriesNotInMap1(Map<String, List<ODProbabilityApiInfo>> map1, Map<String, List<ODProbabilityApiInfo>> map2) {
        Iterator<Map.Entry<String, List<ODProbabilityApiInfo>>> iterator = map2.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, List<ODProbabilityApiInfo>> entry = iterator.next();
            if (!map1.containsKey(entry.getKey())) {
                iterator.remove(); // 删除不在 map1 中的条目
            }
        }
    }
/**
 * @description: 设定站点业务参数：1、进站里面人数的OD概率 2、每秒进站人数
 *
 * @author:  renzhg
 * @date:  2024/11/15 17:06
 **/
    public void initHisInputsParam(Map<String, Map<String, NumPeopEnStationApiInfo>> numPeopEnStationApiInfoMap) {
        lineRooterMap.forEach((k, v) -> {
            //设定站点业务参数：1、进站里面人数的OD概率 2、每秒进站人数
            v.setStationBizParam(numPeopEnStationApiInfoMap);

        });
    }

    /**
     * @description: 处理OD参数并将其分配到相应的线路。
     *
     * @author:  renzhg
     * @date:  2024/11/15 17:36
     **/
    private void OdParamOperate(Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap) {
        lineRooterMap.forEach((k, v) -> {
            List<String> idlist = linesStationMap.get(k).stream()
                    .map(Station::getId) // 提取每个 Station 的 name
                    .collect(Collectors.toList());// 收
            // 创建一个新的Map来存储过滤后的OD概率信息
            Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfoMap4 = new HashMap<>();
            // 根据站点ID过滤OD概率信息
            odProbabilityApiInfoMap.forEach((k1, v1) -> {
               // 检查站点ID是否在列表中
                if (idlist.contains(k1.split("_")[0])) {
                    // 将条目添加到过滤后的Map中
                    odProbabilityApiInfoMap4.put(k1, v1);
                }
            });
            // 将过滤后的Map转换为嵌套的Map结构
            Map<String, Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfoMap3 = transformMap(odProbabilityApiInfoMap4);
            // 设置当前线路的OD概率信息Map
            v.getLine().setOdProbabilityApiInfoMap(odProbabilityApiInfoMap3);
            // 初始化当前线路的人员负载
            v.getLine().initPersonLoad();
        });
    }


    public Map<String, Map<String, List<ODProbabilityApiInfo>>> transformMap(Map<String, List<ODProbabilityApiInfo>> amap) {
        Map<String, Map<String, List<ODProbabilityApiInfo>>> bmap = new HashMap<>();
        for (Map.Entry<String, List<ODProbabilityApiInfo>> entry : amap.entrySet()) {
            String key = entry.getKey(); // "aa-bb"
            List<ODProbabilityApiInfo> value = entry.getValue(); // 相关的 List<String>
            // 分离出前缀（"aa"）和完整键（"aa-bb"）
            String[] parts = key.split("_");
            String prefixKey = parts[0]; // 获取前缀部分


//             在 bmap 中创建或获取嵌套 Map
            Map<String, List<ODProbabilityApiInfo>> nestedMap = bmap.computeIfAbsent(prefixKey, k -> new HashMap<>());
            // 将当前的键值对放入嵌套 Map
            nestedMap.put(key, value);

//            bmap.put(prefixKey,nestedMap);
        }

        return bmap;
    }

}
